'''
    FileDriver 
'''

from authDSL.drivers import DefaultDriver
import MySQLdb
import cPickle
import pprint
import simplexmlapi



class Database(object):
    
    def __init__(self):
        self._users = {}
        self._auth = [] 
        self._groups = []
    
    def create_user(self, username, passwd):
        self._users[username] = {'passwd': passwd, 'groups':[]}
        
    def authenticate(self, username, passwd):
        if username is not None and passwd is not None and \
        username in self._users and self._users[username]['passwd'] == passwd: 
            self._auth.append(username)
        
    def is_auth(self, username):
        if username in self._auth:
            return True
        return False

    def logout(self, username):
        try:
            self._auth.remove(username)
        except:
            pass
    
    def create_group(self, group):
        if group is not None and group not in self._groups:
            self._groups.append(group)
            
    def delete_group(self, group):
        if group in self._groups:
            try:
                self._groups.remove(group)
            except:
                pass
            for usr in self._users:
                try:
                    usr['groups'].remove(group)
                except:
                    pass
    
    def add_group(self, username, group):
        self.create_group(group)
        if group in self._groups:
            if username is not None and group is not None \
            and username in self._users and group not in self._users[username]["groups"]:
                self._users[username]["groups"].append(group)

    def has_group(self, username, group):
        if username is not None and group is not None \
        and username in self._users and group in self._users[username]["groups"]:
            return True
        return False
    
    def exists_user(self, username):
        if username is not None and username in self._users:
            return True
        return False
    
    def exists_group(self, group):
        if group in self._groups:
            return True
        return False
    

class FileDriver(object):
    
    def __init__(self):
        self._file_name = None
        self.read_config_file()
        self._data = None
        self.load_data()
        if self._data is None:
            self._data = Database()
            
    def read_config_file(self):
        with open('authDSL/drivers/FileDriver/config.xml', 'r') as f:
            read_data = f.read()
        f.closed
        config = simplexmlapi.loads(read_data)
        if config is not None:
            self._file_name = '/tmp/tmp_file' if config.file is None else config.file._
    
    def save_data(self):
        fo = open(self._file_name, "wb")
        cPickle.dump(self._data, fo)
        fo.close()

    def load_data(self):
        try:
            fo = open(self._file_name, "rb")
        except IOError:
            print "Didn't find file %s." % self._file_name
            return
        try:
            self._data = cPickle.load(fo)
        except:
            print "Can't unmarshall content from file %s." % self._file_name
        fo.close()
        
    def get_data(self):
        return self._data
    

file_driver = FileDriver()

#
# Decorators
#

class Decorators(DefaultDriver.Decorators):
    
    @staticmethod
    def is_auth(func):
        def wrap(f):
            def wrapped_f(*args):
                user = args[0]
                data = file_driver.get_data()
                if data is not None and user is not None and data.is_auth(user):
                    f(*args)
                else:
                    print "Usuario nao tem permissao para acessar metodo"
            return wrapped_f
        return wrap(func)
    
    @staticmethod
    def has_group(group):
        def wrap(f):
            def wrapped_f(*args):
                user = args[0]
                data = file_driver.get_data()
                if data is not None and data.exists_user(user) and data.exists_group(group):
                    if data.has_group(user, group): 
                        f(*args)
                    else:
                        print "Usuario nao possui grupo"
                else:
                    print "Usuario ou grupo inexistentes"
            return wrapped_f
        return wrap
   


#
# Authentication functions
#

class Authentication(DefaultDriver.Authentication):
    """
    Class that defines functions for authentication. 
    """
   
    def __init__(self):
        pass
    
    def create_user(self, user, password):
        data = file_driver.get_data()
        if data is not None and not data.exists_user(user):
            data.create_user(user, password)
            file_driver.save_data()
        else:
            print "Usuario ja existe"
    
    def authenticate(self, user, password):
        data = file_driver.get_data()
        result = None
        if data is not None:
            result = data.authenticate(user, password)
            file_driver.save_data()
            if result == False: 
                print "Usuario e senha errados"
        return result
    
    def logout(self, user):
        data = file_driver.get_data()
        if data is not None:
            data.logout(user)
            file_driver.save_data()
            return True
        return False
    
    def add_group(self, user, group):
        data = file_driver.get_data()
        if data is not None:
            data.add_group(user, group)
            file_driver.save_data()
            return True
        return False
    
    def remove_group(self, group):
        data = file_driver.get_data()
        if data is not None:
            data.delete_group(group)
            file_driver.save_data()
            return True
        return False

    
    
    
